#include "../includes.h"


TOD_	TOD;
R_TOD_	R_TOD;
F_TOD_ 	F_TOD;

char TEMP_TOD, TEMP_TOD_MADE;

char month[12] = {31,28,31,30,31,30,31,31,30,31,30,31};

unsigned char MonitorCmd;
char tod_enable_first = 0;
int tod_been_out = 0;

void TOD_OUT(int,char);
void IncrementTOD(void);
time_ setLocalTime(char localh, char localm);
time_ setLocalTimeNew(time_ SrcTime, char localh, char localm);
void increase_second(time_	*);
void DisplayTime();

void SetfpgaTOD(int baud);
void OutputTOD(char *s,int len);

int	tod_check_enable_counter;
void Init_TOD()
{
    SYSTEM.TIME.CUR.YEAR =          0;
    SYSTEM.TIME.CUR.MONTH =         0;
    SYSTEM.TIME.CUR.DAY =           0;
    SYSTEM.TIME.CUR.HOUR =          0;
    SYSTEM.TIME.CUR.MINUTE =        0;
    SYSTEM.TIME.CUR.SECOND =        0;

    SYSTEM.TIME.GPS = SYSTEM.TIME.CUR;
    SYSTEM.TIME.UTC = SYSTEM.TIME.CUR;
    SYSTEM.TIME.MID = SYSTEM.TIME.CUR;
    SYSTEM.EB.TIME = SYSTEM.TIME.CUR;
	SYSTEM.TIME.TOUT = SYSTEM.TIME.CUR;

    SYSTEM.TIME.TIMEMODE =      TIMEMODE_GPS;

    SYSTEM.TIME.LOCALHOUR =     UNDEFINED;
    SYSTEM.TIME.LOCALMINUTE =   UNDEFINED;
    SYSTEM.TIME.ANTDLY =        UNDEFINED;
    SYSTEM.TIME.LEAPSECOND =    0;
    SYSTEM.TIME.LEAPSECPENDING =    UNDEFINED;

    SYSTEM.TIME.TOD_MismatchCounter = 0;
    SYSTEM.TIME.TOD_MatchCounter = 0;
    SYSTEM.TIME.Valid = NO;

	TOD.SKIP_TIMER = 0;
	TOD.SKIP_TOD_TIMER = 0;
	TEMP_TOD = OFF;
	TEMP_TOD_MADE = OFF;
	

	TOD.match_counter = 0;

	//TOD.turn = OFF;
	TOD.turn = ON;
	//DisableTODPortTx();
	MonitorCmd = false;
	tod_check_enable_counter = 0;
	
	TOD.printon = OFF;

	SetfpgaTOD(38400);	//120608 sewon
}


void set_tod_port_high(void)
{

}



#define	Set_0_Bit(X,Y);   (X)&=(~Y);
#define	Set_1_Bit(X,Y);   (X)|=(Y);



char first_lock_reckon = 0;
int prev_tfom_val = 0;
int prev_coast_val = 0;
int prev_rec_val = 0;
int sync_forecast_tod = 0;
void UpdateTOD()
{
    int i,aday;
    int tfom_val;
    int coast_val;
    int rec_val;
    int t1;

	tfom_val = 0;
	coast_val = 0;
	rec_val = 0;
	

	//==========================================================================================
	//TOD STATUS
	//==========================================================================================
	TOD.status = 0;


	if( DIAG.OSC == FAIL){
		Set_1_Bit(TOD.status,BIT_STATUS_OSC_FAIL);
	}
	

	if( !HEALTH.EB ){
		Set_1_Bit(TOD.status,BIT_STATUS_GPS_FAIL);
	}


	if(TOD.status & BIT_STATUS_GPS_FAIL)
	{
		Set_1_Bit(TOD.status,BIT_STATUS_HOLD_OVER);
	}
	//if(LOCK_REFERENCE){
	//	if(SYSTEM.OPERATION.LOCKMODE==HOLDOVER_OVER10MIN){	
	//		Set_1_Bit(TOD.status,BIT_STATUS_HOLD_OVER);
	//	}
	//}
	dbgCV(3326)	printf("tod.status : %d\n",TOD.status);

	t1 = abs((int)(CONTROL.AvgTimeOffset*BILLION));

	if( (FIRST_LOCK) && !(TOD.status & BIT_STATUS_HOLD_OVER)) {

		if ( t1 < 10 ) {			DIAG.TFOM = 2;	}
		else if ( t1 < 100 ) {		DIAG.TFOM = 3;	}
		else if ( t1 < 1000 ) {		DIAG.TFOM = 4;	}
		else if ( t1 < 10000 ) {	DIAG.TFOM = 5;	}
		else if ( t1 < 100000 ) {	DIAG.TFOM = 6;	}
		else if ( t1 < 1000000 ) {	DIAG.TFOM = 7;	}
		else if ( t1 < 10000000 ) {	DIAG.TFOM = 8;	}
		else {						DIAG.TFOM = 9;	}
	}
	else {
		DIAG.TFOM = 9;
	}

///////////////Error Byte
///////////////Error Byte
///////////////Error Byte
//#define BIT_ERROR_TFOM				0x40
//#define BIT_ERROR_A_OPEN			0x20
//#define BIT_ERROR_B_OPEN			0x10
//#define BIT_ERROR_A_FUNC_FAIL			0x08
//#define BIT_ERROR_B_FUNC_FAIL			0x04
//#define BIT_ERROR_FAN_OPEN			0x02
//#define BIT_ERROR_FAN_FAIL			0x01
	//==========================================================================================
	//TOD ERROR CODE
	//==========================================================================================
	TOD.error = 0;

	if( DIAG.TFOM > 4 ) {
		//if((TOD.opmode&0xC0) != BIT_OPMODE_COAST){
		if(!(	TOD.status & BIT_STATUS_HOLD_OVER)){ 
			Set_1_Bit(TOD.error,BIT_ERROR_TFOM);
			tfom_val = 1;
		}
	}
	if( DIAG.i_exist == NO ){
		if(SYSTEM.ID == ModuleA){  	Set_1_Bit(TOD.error, BIT_ERROR_A_OPEN); }
		else{ 				Set_1_Bit(TOD.error, BIT_ERROR_B_OPEN); }
	}
	//if( !CounterModule.EXIST ){
	//	if(SYSTEM.ID == ModuleA){  	Set_1_Bit(TOD.error, BIT_ERROR_B_OPEN); }
	//	else{ 				Set_1_Bit(TOD.error, BIT_ERROR_A_OPEN); }
	//}
	
	if( QueryFANOPEN() )
	{
		Set_1_Bit(TOD.error, BIT_ERROR_FAN_OPEN); 
	}
	if( QueryFANError() )
	{
		Set_1_Bit(TOD.error, BIT_ERROR_FAN_FAIL); 
	}
	
	//DIAG.EB, DIAG.OCXO, DIAG.EFC, DIAG.POWER
	

	if((DIAG.SYSTEM == FAIL) || (TOD.status&BIT_STATUS_HOLD_OVER) || (DIAG.i_exist == NO) || (tod_been_out<1))
	{
		if(SYSTEM.ID == ModuleA){  	Set_1_Bit(TOD.error, BIT_ERROR_A_FUNC_FAIL); }
		else					{ 	Set_1_Bit(TOD.error, BIT_ERROR_B_FUNC_FAIL); }
		
		SetFuncFail();
	}
	else{
		ResetFuncFail();
	}
	
	if( CounterModule.EXIST ){ // later, it should be replaced with CounterModule.Rx Valid Flag if possible

		if(SYSTEM.ID == ModuleA){
			TOD.error |= (CounterModule.error & BIT_ERROR_B_FUNC_FAIL );
		}
		else{
			TOD.error |= (CounterModule.error & BIT_ERROR_A_FUNC_FAIL );
		}
	}
	else{
		if(SYSTEM.ID == ModuleA){  	Set_1_Bit(TOD.error, (BIT_ERROR_B_OPEN|BIT_ERROR_B_FUNC_FAIL)); }
		else					{ 	Set_1_Bit(TOD.error, (BIT_ERROR_A_OPEN|BIT_ERROR_A_FUNC_FAIL)); }
	}
	//if(prev_tfom_val != tfom_val &&
	//	STATUS_Warmup==OFF && 
	//	(SYSTEM.OPERATION.STATUS == STATUS_ACTIVE || SYSTEM.OPERATION.STATUS == STATUS_STANDBY)){
	//	LogIt(LOG_TFOM, tfom_val);
	//	prev_tfom_val = tfom_val;
	//}
	
	//if( DIAG.TFOM > 4 ) {
	//	Set_1_Bit(TOD.error,BIT_ERROR_TFOM);
	//}


	//==========================================================================================
	//TOD OPMODE
	//Active/Standby LOCK, Warmup
	//==========================================================================================
	TOD.opmode = 0;

#define M_OPER_FIELD_A (wbD5|wbD4)	
#define M_OPER_FIELD_B (wbD3|wbD2)	

	if(FIRST_LOCK && STATUS_Warmup == OFF){
		first_lock_reckon = 1;
		if(TOD.status&BIT_STATUS_HOLD_OVER){
			if(SYSTEM.ID == ModuleA){	Set_1_Bit(TOD.opmode,BIT_OPMODE_COAST_A);	}
			else{				Set_1_Bit(TOD.opmode,BIT_OPMODE_COAST_B);	}
			coast_val = 1;
		}
		else if(DIAG.TFOM > 4 ){
			if(SYSTEM.ID == ModuleA){	Set_1_Bit(TOD.opmode,BIT_OPMODE_RECOVER_A);	}
			else{				Set_1_Bit(TOD.opmode,BIT_OPMODE_RECOVER_B);	}
			rec_val = 1;
		}
		else{
			if(SYSTEM.ID == ModuleA){	Set_1_Bit(TOD.opmode,BIT_OPMODE_LOCKED_A);	}
			else{				Set_1_Bit(TOD.opmode,BIT_OPMODE_LOCKED_B);	}
		}
	}
	else
	{
		if((GC.RunningTime >= 30*60) && (TOD.status & BIT_STATUS_GPS_FAIL)) {
			if(SYSTEM.ID == ModuleA){	Set_1_Bit(TOD.opmode,BIT_OPMODE_COAST_A);	}
			else{				Set_1_Bit(TOD.opmode,BIT_OPMODE_COAST_B);	}
			coast_val = 1;
		}
		else {
			if(SYSTEM.ID == ModuleA){	Set_1_Bit(TOD.opmode,BIT_OPMODE_WARMUP_A);	}
			else{				Set_1_Bit(TOD.opmode,BIT_OPMODE_WARMUP_B);	}
		}
	}
	
	if(SYSTEM.ID == ModuleA){	TOD.opmode |= ((TOD.opmode<<2)&(wbD7|wbD6) ); }
	else{				TOD.opmode |= ((TOD.opmode<<4)&(wbD7|wbD6) ); }

	if(((STATUS_Warmup==OFF) && (SYSTEM.OPERATION.STATUS == STATUS_ACTIVE)) && 
		(SYSTEM.OPERATION.OPMODE == OPMODE_OPERATION))
	{
		Set_0_Bit(TOD.opmode,BIT_OPMODE_INIT);
	}
	else{
		Set_1_Bit(TOD.opmode,BIT_OPMODE_INIT);
	}
	
	if(sync_forecast_tod){
		Set_1_Bit(TOD.opmode,BIT_OPMODE_RESYNC);
	}
	
	if( CounterModule.EXIST ){ // later, it should be replaced with CounterModule.Rx Valid Flag if possible

		if(SYSTEM.ID == ModuleA){
			TOD.opmode |= (CounterModule.opmode & M_OPER_FIELD_B );
		}
		else  TOD.opmode |= (CounterModule.opmode & M_OPER_FIELD_A );
	}
	else{
		if(SYSTEM.ID == ModuleA){   }
		else					{ 	}
	}
	
	if(prev_coast_val != coast_val){
		LogIt(LOG_CATA1_NORM, LOG_CATA2_NOTHING, LOG_COAST, coast_val);
	}
	prev_coast_val = coast_val;
	
	if(prev_rec_val != rec_val){
		LogIt(LOG_CATA1_NORM, LOG_CATA2_NOTHING, LOG_RECOVERY, rec_val);
	}
	prev_rec_val = rec_val;
	
	
	

	//==========================================================================================
	//TOD INFORM
	//==========================================================================================

//#define M_INFORM_FIELD_A (wbD7|wbD5|wbD3|wbD2)	
//#define M_INFORM_FIELD_B (wbD6|wbD5|wbD1|wbD0)	
#define M_INFORM_FIELD_A (wbD7|wbD3|wbD2)	
#define M_INFORM_FIELD_B (wbD6|wbD1|wbD0)	
	
	TOD.inform = 0;
	
	if( DIAG.TFOM > 4){
		if(SYSTEM.ID == ModuleA){
			Set_1_Bit(TOD.inform,BIT_INFO_OVER_TFOM_A);
		}
		else{
			Set_1_Bit(TOD.inform,BIT_INFO_OVER_TFOM_B);
		}
	}	

	
	if( (SYSTEM.OPERATION.STATUS == STATUS_ACTIVE) ){
		if(SYSTEM.ID == ModuleA){  Set_0_Bit(TOD.inform,BIT_INFO_ACT_MODULE); }
		else{ Set_1_Bit(TOD.inform,BIT_INFO_ACT_MODULE); }
	}
	
	if( CONFIG.AntCheckFlag == NO ){
		if(SYSTEM.ID == ModuleA){
			Set_1_Bit(TOD.inform,BIT_INFO_ANT_DISABLED_A);
		}
		else{
			Set_1_Bit(TOD.inform,BIT_INFO_ANT_DISABLED_B);
		}
	} 
	else{
		if( ant_short_time>59 ){
			if(SYSTEM.ID == ModuleA){  Set_1_Bit(TOD.inform,BIT_INFO_ANT_SHORT_A); }
			else{ Set_1_Bit(TOD.inform,BIT_INFO_ANT_SHORT_B); }
		}
	
		else if( ant_open_time>59 ){
			if(SYSTEM.ID == ModuleA){ Set_1_Bit(TOD.inform,BIT_INFO_ANT_OPEN_A); }
			else{ Set_1_Bit(TOD.inform,BIT_INFO_ANT_OPEN_B); }
		}
	}

	if( CounterModule.EXIST ){ // later, it should be replaced with CounterModule.Rx Valid Flag if possible

		if(SYSTEM.ID == ModuleA){
			TOD.inform |= (CounterModule.inform & M_INFORM_FIELD_B );
		}
		else  TOD.inform |= (CounterModule.inform & M_INFORM_FIELD_A );
	}
	else{
		if(SYSTEM.ID == ModuleA){   }
		else					{ 	}
	}

	
	//==========================================================================================


//	R_TOD.year10 	= (SYSTEM.TIME.CUR.YEAR%100)/10;
//	R_TOD.year1 	= SYSTEM.TIME.CUR.YEAR%10;
//	// Days
//    	for( i = 0, aday 	= (int)SYSTEM.TIME.CUR.DAY; i < SYSTEM.TIME.CUR.MONTH - 1; i++){
//        	aday += month[i];
//    	}
//	R_TOD.day100 	= aday/100;
//	R_TOD.day10 	= (aday%100)/10;
//	R_TOD.day1 		= aday%10;
//
//	R_TOD.hour10 	= SYSTEM.TIME.CUR.HOUR/10;
//	R_TOD.hour1 	= SYSTEM.TIME.CUR.HOUR%10;
//	R_TOD.minute10 	= SYSTEM.TIME.CUR.MINUTE/10;
//	R_TOD.minute1 	= SYSTEM.TIME.CUR.MINUTE%10;
//	R_TOD.second10 	= SYSTEM.TIME.CUR.SECOND/10;
//	R_TOD.second1 	= SYSTEM.TIME.CUR.SECOND%10;
	R_TOD.year10 	= (SYSTEM.TIME.TOUT.YEAR%100)/10;
	R_TOD.year1 	= SYSTEM.TIME.TOUT.YEAR%10;
	// Days
    	for( i = 0, aday 	= (int)SYSTEM.TIME.TOUT.DAY; i < SYSTEM.TIME.TOUT.MONTH - 1; i++){
        	aday += month[i];
    	}
	R_TOD.day100 	= aday/100;
	R_TOD.day10 	= (aday%100)/10;
	R_TOD.day1 		= aday%10;

	R_TOD.hour10 	= SYSTEM.TIME.TOUT.HOUR/10;
	R_TOD.hour1 	= SYSTEM.TIME.TOUT.HOUR%10;
	R_TOD.minute10 	= SYSTEM.TIME.TOUT.MINUTE/10;
	R_TOD.minute1 	= SYSTEM.TIME.TOUT.MINUTE%10;
	R_TOD.second10 	= SYSTEM.TIME.TOUT.SECOND/10;
	R_TOD.second1 	= SYSTEM.TIME.TOUT.SECOND%10;
	
	// Power-up	
    if( SYSTEM.OPERATION.OPMODE == OPMODE_POWERUP){
    	R_TOD.leapsecond10 	= 0;	// Tens of Leapsecond
    	R_TOD.leapsecond1 	= 0;	// Units of Leapsecond
	}
	else {
	   	R_TOD.leapsecond10 	= SYSTEM.TIME.LEAPSECOND/10;
   		R_TOD.leapsecond1 	= SYSTEM.TIME.LEAPSECOND%10;
   	}
   	
   	/*
   	R_TOD.leapsecond10 	= 0;
   	R_TOD.leapsecond1 	= 0;
   	*/

	R_TOD.status = TOD.status;
	R_TOD.error = TOD.error;
	R_TOD.opmode = TOD.opmode;
	R_TOD.inform = TOD.inform;

	R_TOD.tail = 0x0D;
}

#define TOD_FPGA_READY_STEP 0
#define TOD_FPGA_SEND_STEP 1
#define TOD_FPGA_READ_STEP 2
#define TOD_FPGA_DONE_STEP 3

#define TOD_FPGA_MAX_RETRY 10

int tod_fpga_step = TOD_FPGA_SEND_STEP;
int tod_fpga_tx_fail = 0;
int tod_fpga_rx_fail = 0;

void TOD_OUT_FPGA(void)
{
F_TOD_ ttod;

		tod_fpga_step = TOD_FPGA_READY_STEP;
		tod_fpga_rx_fail = 0;
		tod_fpga_tx_fail = 0;
		//hmlee - flag off
		func.fpga_tod_task = OFF;
		return ;

	switch(tod_fpga_step){
		
		case TOD_FPGA_READY_STEP:
			ioctl(fdFPGA, IOCTL_TOD_GET, &ttod);

			//hmlee - tx is not zero? meaning not ready to send?
			if(ttod.length != 0){
				tod_fpga_tx_fail++;
				
				//hmlee - hopeless
				if(tod_fpga_tx_fail>TOD_FPGA_MAX_RETRY){
					ResetTODFpga();
					tod_fpga_step = TOD_FPGA_DONE_STEP;
					
					sprintf(MESG,"TOD fpga-tx fail: %d !!\n", ttod.length);
					MessageOut(MESG);
					
					LogItString(LOG_CATA1_NORM, LOG_CATA2_FAIL, "TOD fpga tx");
				}
			}
			else{
				tod_fpga_step = TOD_FPGA_SEND_STEP;
			}
			break;
			
		case TOD_FPGA_SEND_STEP:
			F_TOD.fpga_addr = 45;
			F_TOD.length = sizeof(R_TOD_);
			
			ioctl(fdFPGA, IOCTL_TOD_SET, &F_TOD);
			tod_fpga_step = TOD_FPGA_READ_STEP;
			break;
			
		case TOD_FPGA_READ_STEP:
			ioctl(fdFPGA, IOCTL_TOD_GET, &ttod);

			if(ttod.length < sizeof(R_TOD_)){
				tod_fpga_rx_fail++;
				
				//hmlee - hopeless
				if(tod_fpga_rx_fail>TOD_FPGA_MAX_RETRY){
					tod_fpga_step = TOD_FPGA_DONE_STEP;
					
					sprintf(MESG,"TOD fpga-rx fail: %d !!\n", ttod.length);
					MessageOut(MESG);
					
					LogItString(LOG_CATA1_NORM, LOG_CATA2_FAIL, "TOD fpga rx");
				}
				//hmlee - retry to send
				else{
					ResetTODFpga();
					tod_fpga_step = TOD_FPGA_SEND_STEP;
				}
			}
			//hmlee - good to go
			else{
				tod_fpga_step = TOD_FPGA_DONE_STEP;
				tod_fpga_rx_fail = 0;
				tod_been_out++;
				if(tod_been_out>10){tod_been_out=20;};
			}
			break;
			
		case TOD_FPGA_DONE_STEP:
		default:
			tod_fpga_step = TOD_FPGA_READY_STEP;
			tod_fpga_rx_fail = 0;
			tod_fpga_tx_fail = 0;
			//hmlee - flag off
			func.fpga_tod_task = OFF;
			break;
	}
}

//12-05-18 TOD_Checksum sewon
char TOD_Checksum(char *buf)
{
	int i;
	char check_sum[4];
	char checksum=buf[1];
	for(i=2;buf[i]!='*';i++){
		checksum^=buf[i];
	}
	dbgCV(3325)	printf("checksum : %x",checksum);
	return checksum;
}

void TOD_OUT(int port,char mode)
{

	int i, TxNo;
	char string[20],message[100];
	int byte = 0;
	char checksum;
	char check_sum[5];
	register unsigned char *buffer = (unsigned char*)(&R_TOD);


	switch(mode){

		case	ASCII:
					sprintf(MESG,"[[%d,%5d,%5d],V,%d,EB,%d,%d,%d,%2d,%2d,%2d]",
									SYSTEM.TIME.TOD_MismatchCounter,SYSTEM.TIME.TOD_MatchCounter,TimeSliceCounter,
									SYSTEM.TIME.Valid,
									SYSTEM.EB.TIME.YEAR,SYSTEM.EB.TIME.MONTH,SYSTEM.EB.TIME.DAY,
									SYSTEM.EB.TIME.HOUR,SYSTEM.EB.TIME.MINUTE,SYSTEM.EB.TIME.SECOND);
					TransmitMessage((BYTE*)MESG,PORT_CONTROL);

 					message[0] = (char)0;
					for( i = 0; i < 18; i++){
						string[0] = hex_char[(buffer[i]>>4)&0xf];
						string[1] = hex_char[ buffer[i]    &0xf];
						string[2] = ' ';
						strncat(message,string,3);
					}
					
    				strcat(message,"\r\n");
    				TransmitMessage((BYTE*)message,port);
					break;

		case	BINARY:

   					//kang TransmitnMessage((BYTE *)buffer,18,port);
   					
//   					//if( byte = write(fdTOD, buffer, 18) == -1 ){
//
////printf("\r\n##### TOD WRITE FAIL : %s #####\r\n",strerror(errno));
////sprintf(MESG,"TOD write fail: %s",strerror(errno));
////LogItString(MESG);
//						//printf("\r\nWrite TOD failed");
//					}	
//					else{	
//						//printf("\r\nWrite TOD sucess");
//					}

//					while((byte = write(fdTOD,buffer,18)) == -1){
//						//printf("\r\n##### TOD WRITE FAIL : %s #####\r\n",strerror(errno));
//					}
//					tod_been_out++;
//					if(tod_been_out>10){tod_been_out=20;};


					break;
		case UART_CONTROL:
			//12-05-18 Sewon
					sprintf(message,"$TOD,%d,%d,%02d,%02d,%02d,%02d,%02d*",
							SYSTEM.TIME.Valid,
							SYSTEM.TIME.TOUT.YEAR,SYSTEM.TIME.TOUT.MONTH,SYSTEM.TIME.TOUT.DAY,
							SYSTEM.TIME.TOUT.HOUR,SYSTEM.TIME.TOUT.MINUTE,SYSTEM.TIME.TOUT.SECOND);

					checksum = TOD_Checksum(message);

					check_sum[0]=hex_char[ (checksum&0xF0)>>4 ];
					check_sum[1]=hex_char[ (checksum&0x0F) ];
					check_sum[2]='\r';
					check_sum[3]='\n';
					check_sum[4]=0;

					strcat(message,check_sum);

					OutputTOD(message,strlen(message));

					dbgCV(3366)	printf("%s",message);

					break;
	}
}



void IncrementTOD()
{
	int i;
	int pday,aday,t2;
	signed char carry;
	signed char t1;

	// leap second operation by UTC time reference
	// only for plus pending!!
	
	// 1. Increase GPS time
	increase_second(&SYSTEM.TIME.GPS);
	
	month[1] = 28;

	if (SYSTEM.TIME.GPS.YEAR%4 == 0)    month[1] = 29;
	if (SYSTEM.TIME.GPS.YEAR%100 == 0)  month[1] = 28;
	if (SYSTEM.TIME.GPS.YEAR%400 == 0)  month[1] = 29;


	for( i = 1980, pday = 0; i < SYSTEM.TIME.GPS.YEAR; i++){
		if( ((i%4 == 0) && (i%100 != 0)) || (i%400 == 0)){
			pday += 31622400; // 366
		}
		else {
			pday += 31536000; // 365
		}
	}
	// GPS
	pday -= 432000; // 1980.1.1 ~ 1980.1.5

	for( i = 0, aday = 0; i < SYSTEM.TIME.GPS.MONTH - 1; i++){
		aday += month[i];
	}

	GC.ACCsecond = pday + aday*86400 + (int)(SYSTEM.TIME.GPS.DAY-1)*86400 + (int)(SYSTEM.TIME.GPS.HOUR)*3600 +
					(int)(SYSTEM.TIME.GPS.MINUTE)*60 + (int)SYSTEM.TIME.GPS.SECOND;


	
	if ( SYSTEM.TIME.LEAPSECPENDING == NOW ){

		//fprintf(out," Leap second insertion here!!\n");

		SYSTEM.TIME.LEAPSECPENDING = NO;
		// Plus only!!!
		SYSTEM.TIME.UTC.SECOND = 60;

		SYSTEM.TIME.LEAPSECOND++;

		carry = -1;

	} else {

		t1 = SYSTEM.TIME.GPS.SECOND - SYSTEM.TIME.LEAPSECOND;
		if ( t1 >= 60 ){
			SYSTEM.TIME.UTC.SECOND = t1 - 60;		carry = 1;
		} else if ( t1 < 0 ) {
			SYSTEM.TIME.UTC.SECOND = 60 + t1;		carry = -1;
		} else {
			SYSTEM.TIME.UTC.SECOND = t1;			carry = 0;
		}
    }

	// minute
	t1 = SYSTEM.TIME.GPS.MINUTE + carry;
	if ( t1 >= 60 ){
		SYSTEM.TIME.UTC.MINUTE = t1 - 60;		carry = 1;
	} else if ( t1 < 0 ) {
		SYSTEM.TIME.UTC.MINUTE = 60 + t1;		carry = -1;
	} else {
		SYSTEM.TIME.UTC.MINUTE = t1;			carry = 0;
	}

	// Hour
	t1 = SYSTEM.TIME.GPS.HOUR + carry;
	if ( t1 >= 24 ){
		SYSTEM.TIME.UTC.HOUR = t1 - 24;		carry = 1;
	} else if ( t1 < 0 ) {
		SYSTEM.TIME.UTC.HOUR = 24 + t1;		carry = -1;
	} else {
		SYSTEM.TIME.UTC.HOUR = t1;			carry = 0;
	}


	// second try
	aday += ((int)SYSTEM.TIME.GPS.DAY + (int)carry);

	// in case of 1/1 ( january first
	if ( aday == 0 ) {
		SYSTEM.TIME.UTC.DAY = 31;
		SYSTEM.TIME.UTC.MONTH = 12;
		carry = -1;
	} else {
		for( i = 0, t2=0; i < 12; i++ ) {
			if( aday <= t2 + (int)month[i]) {
				SYSTEM.TIME.UTC.DAY = (BYTE)(aday-t2);
				SYSTEM.TIME.UTC.MONTH = (BYTE)(i+1);
				carry = 0;

				//fprintf(out," %d %ld %ld ",SYSTEM.TIME.GPS.DAY,aday,t2);
				break;
			}
			t2 += (int)month[i];
		}
		if ( i == 12 ) {
			SYSTEM.TIME.UTC.DAY = 1;
			SYSTEM.TIME.UTC.MONTH = 1;
			carry = 1;
		}
	}


	//Year 
	SYSTEM.TIME.UTC.YEAR = (short)SYSTEM.TIME.GPS.YEAR + (short)carry;
	
	if( ( SYSTEM.TIME.LEAPSECPENDING == PLUS ) &&

		(	(SYSTEM.TIME.UTC.MONTH == 12 && SYSTEM.TIME.UTC.DAY == 31) ||
			(SYSTEM.TIME.UTC.MONTH == 6  && SYSTEM.TIME.UTC.DAY == 30) ||
			(SYSTEM.TIME.UTC.MONTH == 3  && SYSTEM.TIME.UTC.DAY == 31) ||
			(SYSTEM.TIME.UTC.MONTH == 9  && SYSTEM.TIME.UTC.DAY == 30) 	)  	&&
		( 	(SYSTEM.TIME.UTC.HOUR  == 23) &&
			(SYSTEM.TIME.UTC.MINUTE == 59) &&
			(SYSTEM.TIME.UTC.SECOND == 59)    ) ) {

		  SYSTEM.TIME.LEAPSECPENDING = NOW;
	}
	
	SYSTEM.TIME.CUR = setLocalTime(SYSTEM.TIME.LOCALHOUR, SYSTEM.TIME.LOCALMINUTE);
	
	//printf("After  SYSTEM.TIME.CUR : %4d, %2d, %2d, %2d, %2d, %2d\n",SYSTEM.TIME.CUR.YEAR,SYSTEM.TIME.CUR.MONTH,SYSTEM.TIME.CUR.DAY,SYSTEM.TIME.CUR.HOUR,SYSTEM.TIME.CUR.MINUTE,SYSTEM.TIME.CUR.SECOND);
	
}


void increase_second_amount(time_	*time, signed char amount)
{
	signed char carry;
	signed char t1;

	month[1] = 28;

	if (time->YEAR%4 == 0)    month[1] = 29;
	if (time->YEAR%100 == 0)  month[1] = 28;
	if (time->YEAR%400 == 0)  month[1] = 29;

//	time->SECOND++;
//	if( time->SECOND >= 60 ){
//		time->SECOND = 0;			carry = 1;
//	} else {
//		carry = 0;
//	}
	time->SECOND = time->SECOND+amount;
	if( time->SECOND >= 60 ){
		time->SECOND = time->SECOND-60;			carry = 1;
	} else {
		carry = 0;
	}

	time->MINUTE += (BYTE)carry;
	if( time->MINUTE >= 60 ){
		time->MINUTE = 0;        carry = 1;
	} else {
		carry = 0;
	}

	time->HOUR += (BYTE)carry;
	if( time->HOUR >= 24 ){
		time->HOUR = 0;        carry = 1;
	} else {
		carry = 0;
	}

	time->DAY += (BYTE)carry;
	if( time->DAY >= (month[time->MONTH-1]+1)){
		time->DAY = 1;        carry = 1;
	} else {
		carry = 0;
	}

	time->MONTH += (BYTE)carry;
	if( time->MONTH >= 13 ){
		time->MONTH = 1;        carry = 1;
	} else {
		carry = 0;
	}

	time->YEAR += (BYTE)carry;
}




time_ setLocalTime(char localh, char localm)
{
	time_	CUR;
	signed char carry;
	signed char t1;
	
	
	//printf("Before SYSTEM.TIME.CUR : %4d, %2d, %2d, %2d, %2d, %2d\n",SYSTEM.TIME.CUR.YEAR,SYSTEM.TIME.CUR.MONTH,SYSTEM.TIME.CUR.DAY,SYSTEM.TIME.CUR.HOUR,SYSTEM.TIME.CUR.MINUTE,SYSTEM.TIME.CUR.SECOND);
	
		
	switch ( SYSTEM.TIME.TIMEMODE ){
		case	TIMEMODE_UTC:	CUR = SYSTEM.TIME.UTC;	break;
		case	TIMEMODE_GPS:	CUR = SYSTEM.TIME.GPS;	

				//printf("SYSTEM.TIME.GPS : %4d, %2d, %2d, %2d, %2d, %2d\n",SYSTEM.TIME.GPS.YEAR,SYSTEM.TIME.GPS.MONTH,SYSTEM.TIME.GPS.DAY,SYSTEM.TIME.GPS.HOUR,SYSTEM.TIME.GPS.MINUTE,SYSTEM.TIME.GPS.SECOND);
					return CUR;
					
		default:	CUR = SYSTEM.TIME.GPS;	return CUR;

	}

	// Minute
	if(CUR.HOUR > 0){
		t1 = (char)CUR.MINUTE + localm;
	} else {
		t1 = (char)CUR.MINUTE - localm;
	}

	if ( t1 >= 60 ){
		CUR.MINUTE = t1 - 60;		carry = 1;
	} else if ( t1 < 0 ) {
		CUR.MINUTE = 60 + t1;		carry = -1;
	} else {
		CUR.MINUTE = t1;			carry = 0;
	}
	// Hour
	t1 = (char)CUR.HOUR + localh + carry;
	if ( t1 >= 24 ){
		CUR.HOUR = t1 - 24;		carry = 1;
	} else if ( t1 < 0 ) {
		CUR.HOUR = 24 + t1;		carry = -1;
	} else {
		CUR.HOUR = t1;			carry = 0;
	}

	// Day
	t1 = (char)CUR.DAY + carry;
	if ( t1 > month[CUR.MONTH-1] ){
		CUR.DAY = 1;
		carry = 1;
	} else if ( t1 <= 0 ) {
		if (CUR.MONTH > 1 ){
			CUR.DAY = month[CUR.MONTH-2] ;
		} else {
			CUR.DAY = 31;
		}
		carry = -1;
	} else {
		CUR.DAY = t1;
		carry = 0;
	}

	// MONTH
	t1 = (char)CUR.MONTH + carry;
	if ( t1 > 12 ){
		CUR.MONTH = 1;
		carry = 1;
	} else if ( t1 <= 0 ) {
		CUR.MONTH = 12;
		carry = -1;
	} else {
		CUR.MONTH = t1;
		carry = 0;
	}

	//Year
	CUR.YEAR = (short)CUR.YEAR + (short)carry;

	return CUR;
}

time_ setLocalTimeNew(time_ SrcTime, char localh, char localm)
{

	signed char carry;
	signed char t1;

	// Minute
	if(SrcTime.HOUR > 0){
		t1 = (char)SrcTime.MINUTE + localm;
	} else {
		t1 = (char)SrcTime.MINUTE - localm;
	}

	if ( t1 >= 60 ){
		SrcTime.MINUTE = t1 - 60;
		carry = 1;
	} else if ( t1 < 0 ) {
		SrcTime.MINUTE = 60 + t1;
		carry = -1;
	} else {
		SrcTime.MINUTE = t1;
		carry = 0;
	}
	// Hour
	t1 = (char)SrcTime.HOUR + localh + carry;
	if ( t1 >= 24 ){
		SrcTime.HOUR = t1 - 24;
		carry = 1;
	} else if ( t1 < 0 ) {
		SrcTime.HOUR = 24 + t1;
		carry = -1;
	} else {
		SrcTime.HOUR = t1;
		carry = 0;
	}

	// Day
	t1 = (char)SrcTime.DAY + carry;
	if ( t1 > month[SrcTime.MONTH-1] ){
		SrcTime.DAY = 1;			carry = 1;
	} else if ( t1 <= 0 ) {
		if (SrcTime.MONTH > 1 ){
			SrcTime.DAY = month[SrcTime.MONTH-2] ;
		} else {
			SrcTime.DAY = 31;
		}
		carry = -1;
	} else {
		SrcTime.DAY = t1;
		carry = 0;
	}

	// MONTH
	t1 = (char)SrcTime.MONTH + carry;
	if ( t1 > 12 ){
		SrcTime.MONTH = 1;
		carry = 1;
	} else if ( t1 <= 0 ) {
		SrcTime.MONTH = 12;
		carry = -1;
	} else {
		SrcTime.MONTH = t1;
		carry = 0;
	}

	//Year
	SrcTime.YEAR = (short)SrcTime.YEAR + (short)carry;

	return SrcTime;
}

void UpdateOEMTime()
{
	SYSTEM.EB.TIME.YEAR = timea.utc_year;
	SYSTEM.EB.TIME.MONTH = timea.utc_month;
	SYSTEM.EB.TIME.DAY = timea.utc_day;
	SYSTEM.EB.TIME.HOUR = timea.utc_hour;
	SYSTEM.EB.TIME.MINUTE = timea.utc_min;
	SYSTEM.EB.TIME.SECOND = timea.utc_ms/1000;
	//printf(">>sec %3d, %3d\r\n",SYSTEM.EB.TIME.SECOND, timea.gps_status  );
}

int fwup_glob_state;
char StartTOD()
{

//	UpdateOEMTime();


	if(SYSTEM.EB.STATUS != EB_STATUS_RUN && tod_enable_first == 1){

		return 0;
	}	


	increase_second(&SYSTEM.TIME.MID);

	if(time_debug)
	{
		sprintf(MESG,"<mat:%d,mis:%d> eb,mid,gps)min:%2d,%2d,%2d, sec:%2d,%2d,%2d  \r\n"
			,SYSTEM.TIME.TOD_MatchCounter
			,SYSTEM.TIME.TOD_MismatchCounter

			,SYSTEM.EB.TIME.MINUTE
			,SYSTEM.TIME.MID.MINUTE
			,SYSTEM.TIME.GPS.MINUTE

			,SYSTEM.EB.TIME.SECOND
			,SYSTEM.TIME.MID.SECOND
			,SYSTEM.TIME.GPS.SECOND
		);
			
		TransmitMessage((BYTE*)MESG,PORT_CONTROL);
	}
	
	if( TOD.SKIP_TIMER > 0 ){
			TOD.SKIP_TIMER--;
	}
		
   	if( (SYSTEM.EB.STATUS == EB_STATUS_RUN) && (SYSTEM.OPERATION.LOCKMODE == LOCKED) && /*(RECOVERY.flag == OFF) &&
   		(CHECKLOCK.HoldoverDelayCounter == 0 ) && */( TOD.SKIP_TIMER == 0 ) ) {
   		tod_check_enable_counter++;

   		if(!SYSTEM.TIME.Valid){
	   		//if(tod_check_enable_counter > 120){
	   		if(tod_check_enable_counter > 60){
   				tod_check_enable_counter = 0;
   				CONTROL.SYNC = ON;
   				control_sync_type = 1;
   			}
   		}
   	}

   	//if( (SYSTEM.EB.STATUS == EB_STATUS_RUN) && (SYSTEM.OPERATION.LOCKMODE == LOCKED) && /*(RECOVERY.flag == OFF) &&
   	//	(CHECKLOCK.HoldoverDelayCounter == 0 ) && */( TOD.SKIP_TIMER == 0 ) ) {
	if( SYSTEM.TIME.LEAPSECOND>10 && (SYSTEM.EB.STATUS == EB_STATUS_RUN || tod_enable_first == 0) && (SYSTEM.OPERATION.LOCKMODE == LOCKED || tod_enable_first == 0) && /*(RECOVERY.flag == OFF) &&
   		(CHECKLOCK.HoldoverDelayCounter == 0 ) && */( TOD.SKIP_TIMER == 0 ) ) {
   	

//		if (TOD.time == SYSTEM.EB.TIME) {
		if ( (SYSTEM.TIME.MID.YEAR == SYSTEM.EB.TIME.YEAR) && (SYSTEM.TIME.MID.MONTH == SYSTEM.EB.TIME.MONTH) &&
			(SYSTEM.TIME.MID.DAY == SYSTEM.EB.TIME.DAY) && (SYSTEM.TIME.MID.HOUR == SYSTEM.EB.TIME.HOUR) &&
			(SYSTEM.TIME.MID.MINUTE == SYSTEM.EB.TIME.MINUTE) && (SYSTEM.TIME.MID.SECOND == SYSTEM.EB.TIME.SECOND)  ) {

			SYSTEM.TIME.TOD_MatchCounter++;
			SYSTEM.TIME.TOD_MismatchCounter = 0;
		}
		else {

			SYSTEM.TIME.TOD_MatchCounter = 0;
			SYSTEM.TIME.TOD_MismatchCounter++;
			
			if(SYSTEM.TIME.TOD_MismatchCounter >= 15){
				SYSTEM.TIME.MID = SYSTEM.EB.TIME;
			}
		}

		//if(TOD.match_counter >= 30){
		//kang printf("--TODmCnt: %d --\n",SYSTEM.TIME.TOD_MatchCounter);
		if(SYSTEM.TIME.TOD_MatchCounter >= 15){

			if ( !(	(SYSTEM.TIME.MID.YEAR == SYSTEM.TIME.GPS.YEAR) && (SYSTEM.TIME.MID.MONTH == SYSTEM.TIME.GPS.MONTH) &&
					(SYSTEM.TIME.MID.DAY == SYSTEM.TIME.GPS.DAY) && (SYSTEM.TIME.MID.HOUR == SYSTEM.TIME.GPS.HOUR) &&
					(SYSTEM.TIME.MID.MINUTE == SYSTEM.TIME.GPS.MINUTE) && (SYSTEM.TIME.MID.SECOND == SYSTEM.TIME.GPS.SECOND) )) {

			    //if( SYSTEM.TIME.Valid == NO ){
				//	LogIt(LOG_Start,GC.RunningTime);
				//}
				if((SYSTEM.TIME.Valid == YES) && (fwup_glob_state==0) && (STATUS_Warmup == OFF)){
					LogIt3(LOG_CATA1_NORM, LOG_CATA2_NOTHING, LOG_TOD_CHG_BEFORE,
						SYSTEM.TIME.GPS.YEAR,
						((SYSTEM.TIME.GPS.MONTH<<24)&0xFF000000) |
						((SYSTEM.TIME.GPS.DAY<<16)&0x00FF0000) | 
						((SYSTEM.TIME.GPS.HOUR<<8)&0x0000FF00) | 
						((SYSTEM.TIME.GPS.MINUTE)&0x000000FF),
						((SYSTEM.TIME.GPS.SECOND<<24)&0xFF000000)
					);
					LogIt3(LOG_CATA1_NORM, LOG_CATA2_NOTHING, LOG_TOD_CHG_AFTER,
						SYSTEM.TIME.MID.YEAR,
						((SYSTEM.TIME.MID.MONTH<<24)&0xFF000000) |
						((SYSTEM.TIME.MID.DAY<<16)&0x00FF0000) | 
						((SYSTEM.TIME.MID.HOUR<<8)&0x0000FF00) | 
						((SYSTEM.TIME.MID.MINUTE)&0x000000FF),
						((SYSTEM.TIME.MID.SECOND<<24)&0xFF000000)
					);	
				}
				
				if(tod_enable_first == 0) tod_enable_first = 1;
				SYSTEM.TIME.Valid = YES;
				SYSTEM.TIME.GPS	= SYSTEM.EB.TIME;
				SYSTEM.TIME.LEAPSECOND = SYSTEM.EB.LEAPSECOND;
			}
		}

	}
	
	if(SYSTEM.TIME.TOD_MatchCounter >= 15){
		if(!SYSTEM.TIME.Valid){
				
			if(tod_enable_first == 0) tod_enable_first = 1;
			SYSTEM.TIME.Valid = YES;
			SYSTEM.TIME.LEAPSECOND = SYSTEM.EB.LEAPSECOND;
			//LogIt(LOG_Start,GC.RunningTime);
			LogEbStatus();
		}
	}

	return YES;

}




void increase_second(time_	*time)
{
	signed char carry;
	signed char t1;

	month[1] = 28;

	if (time->YEAR%4 == 0)    month[1] = 29;
	if (time->YEAR%100 == 0)  month[1] = 28;
	if (time->YEAR%400 == 0)  month[1] = 29;

	time->SECOND++;
	if( time->SECOND >= 60 ){
		time->SECOND = 0;			carry = 1;
	} else {
		carry = 0;
	}

	time->MINUTE += (BYTE)carry;
	if( time->MINUTE >= 60 ){
		time->MINUTE = 0;        carry = 1;
	} else {
		carry = 0;
	}

	time->HOUR += (BYTE)carry;
	if( time->HOUR >= 24 ){
		time->HOUR = 0;        carry = 1;
	} else {
		carry = 0;
	}

	time->DAY += (BYTE)carry;
	if( time->DAY >= (month[time->MONTH-1]+1)){
		time->DAY = 1;        carry = 1;
	} else {
		carry = 0;
	}

	time->MONTH += (BYTE)carry;
	if( time->MONTH >= 13 ){
		time->MONTH = 1;        carry = 1;
	} else {
		carry = 0;
	}

	time->YEAR += (BYTE)carry;
}

void DisplayTime()
{
	sprintf(MESG,	"x[1;1H[GPS]%2d/%2d/%2d %2d/%2d/%2d\r\n",
			SYSTEM.TIME.GPS.YEAR,SYSTEM.TIME.GPS.MONTH,SYSTEM.TIME.GPS.DAY, SYSTEM.TIME.GPS.HOUR,SYSTEM.TIME.GPS.MINUTE,SYSTEM.TIME.GPS.SECOND
	);
	MESG[0] = 0x1B;
	TransmitMessage((BYTE*)MESG,PORT_CONTROL);
	
	sprintf(MESG,	"[ EB]%2d/%2d/%2d %2d/%2d/%2d\r\n\r\n",
			SYSTEM.EB.TIME.YEAR, SYSTEM.EB.TIME.MONTH, SYSTEM.EB.TIME.DAY, SYSTEM.EB.TIME.HOUR, SYSTEM.EB.TIME.MINUTE, SYSTEM.EB.TIME.SECOND
	);
	TransmitMessage((BYTE*)MESG,PORT_CONTROL);
	
	sprintf(MESG,	"OPERATION:%d,TOD_SKIP:%d\r\n",
					SYSTEM.OPERATION.LOCKMODE,TOD.SKIP_TIMER);
	TransmitMessage((BYTE*)MESG,PORT_CONTROL);				
					
	
	
	sprintf(MESG,	"[TOD Update Condition]\r\n"
					"    EB.STATUS[%d] EB.PSDM[%d] EB.LOCKMODE[%d] Recovery[%d]\r\n",
					SYSTEM.EB.STATUS, 
					SYSTEM.EB.PSDM, 
					SYSTEM.EB.LOCKMODE, 
					RECOVERY.flag
		);
	TransmitMessage((BYTE*)MESG,PORT_CONTROL);
	
	sprintf(MESG,	"    LMU.STATUS[%d] %d\r\n",
					lmu.STATUS,lmu.rxflag		
		);
	TransmitMessage((BYTE*)MESG,PORT_CONTROL);
	
	sprintf(MESG,	"[TOD Process]\r\n"
					"    Mismatch[%d] Match[%d] Valid[%d]\r\n",
					SYSTEM.TIME.TOD_MismatchCounter,
					SYSTEM.TIME.TOD_MatchCounter,
					SYSTEM.TIME.Valid
					);
	TransmitMessage((BYTE*)MESG,PORT_CONTROL);
					
}

void AutoSendODTCommand()
{
	int val;
	
	if(MonitorCmd == false) return;
	
	val = GC.RunningTime % 10;
	
	//if(val %2 != 0) return;

	if( TimeSliceCounter == 10) ODTCommand(5);
	else if( TimeSliceCounter == 20) ODTCommand(6);
	else if( TimeSliceCounter == 30) ODTCommand(7);
	else if( TimeSliceCounter == 40) ODTCommand(8);
	else if( TimeSliceCounter == 50) ODTCommand(14);
	else if( TimeSliceCounter == 60) ODTCommand(15);
	
	
	switch(val){
		case 0:
				if( TimeSliceCounter == 70) ODTCommand(1);
				else if( TimeSliceCounter == 80) ODTCommand(2);
				else if( TimeSliceCounter == 90) ODTCommand(3);
				break;
		case 2:
				if( TimeSliceCounter == 70)ODTCommand(4);
				else if( TimeSliceCounter == 80)ODTCommand(9);
				else if( TimeSliceCounter == 90)ODTCommand(10);
				break;
		case 4:
				if( TimeSliceCounter == 70)ODTCommand(11);
				else if( TimeSliceCounter == 80)ODTCommand(12);
				break;
		case 6:
				if( TimeSliceCounter == 70)ODTCommand(13);
				else if( TimeSliceCounter == 80)ODTCommand(16);
				break;
		case 8:
				if( TimeSliceCounter == 70)ODTCommand(17);
				else if( TimeSliceCounter == 80)ODTCommand(18);
				else if( TimeSliceCounter == 90)ODTCommand(19);
				break;
	}
			
}

void ODTCommand(int cmd)
{
	//char message[256];
	char message[512];
	//char string[20];
	char string[40];
	int i;
	int 	t1,t2,t3;
	float   f1,f2,f3;
	char    d1,d2;
	char 	str1[6],str2[6],str3[6],str4[6],str5[6],str6[6];
	short	length;
	
	switch(cmd){
		case 1:
				//sprintf(message,"$VERS,%s,%s*\r\n",
				//	FirmWare_Version,Build_date);
				break;
		case 2:
				sprintf(message,"$ANT1,%03d*\r\n",(unsigned)CONFIG.ANTDLY);
				break;
		case 3:
				strcpy(message,"$AZEL");
			 	for( i = 0; i < 12; i++ ){
					sprintf(string,",%.2d,%.2d,%.3d",SYSTEM.TRACK.VIS_SAT[i].ID,SYSTEM.TRACK.VIS_SAT[i].EL,SYSTEM.TRACK.VIS_SAT[i].AZ);
					strcat(message,string);
				}
				strcat(message,"*\r\n");
				break;
		case 4:
				sprintf(message,"$DACP,%d*\r\n",CONTROL.CurrentDAC);
				//sprintf(message,"$DACP,%d*\r\n",CONFIG.DAC);
				break;
		case 5:
				sprintf(message,"$EFER,%+5.3E*\r\n",CONTROL.Frequency);
				break;
		case 6:
				sprintf(message,"$ESSD,%7.1f*\r\n",CONTROL.AvgTimeOffset*BILLION);
				break;
		case 7:
				sprintf(message,"$ESSN,%010d*\r\n",GC.RunningTime);
				break;
		case 8://pp2s counter�ٲ�
				sprintf(message,"$ESTC,%09d*\r\n",0);
				break;
		case 9:
				sprintf(message,"$LEAP,%d*\r\n",SYSTEM.TIME.LEAPSECOND);
				break;
		case 10:
				t1 = SYSTEM.POSITION.AVERAGE.LAT/3600000;  d1 = (t1 > 0) ? 'N':'S';
				f1 = (float)(SYSTEM.POSITION.AVERAGE.LAT%3600000)/60000.0;
				
				t2 = SYSTEM.POSITION.AVERAGE.LON/3600000;  d2 = (t2 > 0) ? 'E':'W';
				f2 = (float)(SYSTEM.POSITION.AVERAGE.LON%3600000)/60000.0;
				f3 = (float)(SYSTEM.POSITION.AVERAGE.HEI/100.0);
				
				sprintf(message,"$PAVG,%d,%07.4f,%c,%d,%07.4f,%c,%07.1f*\r\n",t1,f1,d1,t2,f2,d2,f3);
				break;
		case 11:
				sprintf(message,"$PRID,012,GPSCU*\r\n");
				break;
		case 12:
				strcpy(message,"$SIGP");
				for(i = 0; i < 8; i++){
					//d1 = SYSTEM.TRACK.SAT[i].SS/6;
					d1 = SYSTEM.TRACK.SAT[i].SS;
					//d1 = (d1>9)?9:d1;
					if(SYSTEM.TRACK.SAT[i].STATUS&0x80){	d2 = '1';      	}
					else {									d2 = '0';		}
				
					sprintf(string,",%02d,%d,%c",SYSTEM.TRACK.SAT[i].ID,d1,d2);
					strcat(message,string);
				}
				strcat(message,"*\r\n");
				break;
		case 13:
				/*sprintf(message,"$TMP1,%2d*",RTOD.XOM1_TEMP);*/
				sprintf(message,"$TMP1,%2d*\r\n",(int)TEMPERATURE.CURRENT);
				break;
				break;
		case 14:
				sprintf(message,"$TIMD,%+d*\r\n",(int)(CONTROL.AvgTimeOffset*BILLION));
				break;
		case 15:
				sprintf(message,"$TIME,%.4d,%.2d,%.2d,%.2d,%.2d,%.2d,G,%d*\r\n",
					SYSTEM.TIME.CUR.YEAR,
					SYSTEM.TIME.CUR.MONTH,
					SYSTEM.TIME.CUR.DAY,
					SYSTEM.TIME.CUR.HOUR,
					SYSTEM.TIME.CUR.MINUTE,
					SYSTEM.TIME.CUR.SECOND,
					GC.ACCsecond);
				break;
		case 16:
				sprintf(message,"$MANI,Oscilloquartz*\r\n");
				break;

		case 17:
				str1[0] = str2[0] = str3[0] = str4[0] = str5[0] = str6[0] = 'N'; 
				//Power
				str1[0] = 'P';
				//Alarm
				if(DIAG.POWER == FAIL){str2[0] = 'V';}
				else if(DIAG.EB == FAIL){str2[0] = 'B';}
				else if(DIAG.EFC == FAIL){str2[0] = 'E';}
				else if(DIAG.dDAC == FAIL){str2[0] = 'A';}
				else if((0 & 0x01) && 0 == YES ){str2[0] = 'C';}
				else if(DIAG.i_exist == NO){str2[0] = 'D';}
				else if(DIAG.OSC == FAIL){str2[0] = 'O';}
		
				
				if(FIRST_LOCK && (STATUS_Warmup == OFF)){
					if(SYSTEM.OPERATION.LOCKMODE != HOLDOVER_OVER10MIN) {
						str3[0] = 'L';
					}
					else {
						int holdover_time,value;

						value = (0 & 0x18) >> 3;
						if(value == 0) holdover_time = 2*3600;
						else if(value == 1) holdover_time = 8*3600;
						else if(value == 2) holdover_time = 24*3600;
						if(CHECKLOCK.HoldoverCounter > holdover_time ){
							str3[0] = 'V';
						}	
						else{
							str3[0] = 'D';
						}
					}		
				}
				
				if(STATUS_Warmup == OFF){
			   		if(SYSTEM.OPERATION.STATUS == STATUS_ACTIVE){
						str4[0]= 'A';
					}
					else {
						str4[0] = 'S';
					}
				}
				else{
					if(SYSTEM.OPERATION.OPMODE == OPMODE_POWERUP){}
					else{ str4[0] = 'W';}
				}	
				
				if(0){
					str5[0] = 'P';
				}
									
				//GPS Fault,Ant short, Open, EB Unlocked
				if(DIAG.EB == FAIL) str6[0] = 'E';
				else if(SYSTEM.EB.ANTENNA == ANTENNA_SHORTED) str6[0] = 'S';
				else if(SYSTEM.EB.ANTENNA == ANTENNA_OPENED) str6[0] = 'O';
				else if(SYSTEM.TRACK.TRACKED == 0) str6[0] = 'T';

				sprintf(message,"$XOM1,%c,%c,%c,%c,%c,%c*\r\n",str1[0],str2[0],str3[0],str4[0],str5[0],str6[0]);
				break;
		case 18:
				if(SYSTEM.ID == ModuleA){
					sprintf(message,"$XOMM,A*\r\n");
				}
				else if(SYSTEM.ID == ModuleB){
					sprintf(message,"$XOMM,B*\r\n");
				}
				break;
		case 19:
			switch(SYSTEM.POSITION.PositionMode){
				case POSITION_MODE_KNOWN:
						sprintf(message,"$PMD1,H,0.0*\r\n");
						break;
				case POSITION_MODE_DYNAMIC:
						sprintf(message,"$PMD1,D,0.0*\r\n");
						break;
				default:
						sprintf(message,"$PMD1,A,%4.1f*\r\n",100.0*(float)SYSTEM.POSITION.AveragingCounter/(float)SYSTEM.POSITION.AveragingNo);
						break;
			}
			break;
	}
	
	TransmitMessage((unsigned char*)message,DEBUG_PORT);
}



void SetfpgaTOD(int baud)
{
     //int baud = 38400,
int i,j,k=0;
     int clk=(int)(50e6);
     int div1=4,div2,freq1;
     char buf[200];

     printf("set fpga uart\n");
     //reset uart
//     SetFpgaValue( 15, 0 ); // reset, output disable
     SetFpgaValue( 18, 0 ); // reset, output disable

     div1=4; // div1 should be >=2
     freq1=clk/(baud*4);
     div2=freq1/(div1+2);
//     SetFpgaValue( 13, div1 );
//     SetFpgaValue( 14, div2 );
//     SetFpgaValue( 15, 3 ); // disable reset, output enable
     SetFpgaValue( 15, div1 );
     SetFpgaValue( 16, div2 );
     SetFpgaValue( 18, 3 ); // disable reset, output enable
     printf("div1:%d, div2:%d,%d bps\n",div1,div2,baud);
}

void OutputTOD(char *s,int len)
{
     int i;
     len = min(len,64);
     for(i=0; i< len; i++)
     	     {
//	     SetFpgaValue( 18, s[i] ); //  TOD포트로 출력하는 함수.. 최대 64글자까지 출력가능… 더 출력하고 싶으면 일정시간을 기다린 후에 다시 출력하면 됨.
	     SetFpgaValue( 17, s[i] ); //  TOD포트로 출력하는 함수.. 최대 64글자까지 출력가능… 더 출력하고 싶으면 일정시간을 기다린 후에 다시 출력하면 됨.
     	     }
}
